/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.google.code.p.narcissus.core.reference;

import java.awt.Rectangle;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import com.google.code.p.narcissus.core.NarcissusException;
import com.google.code.p.narcissus.core.model.ReferenceMetaData;
import com.thoughtworks.xstream.XStream;

/**
 * @author jadoj
 */
public class ReferenceMetaDataMapper {

	private static final Logger logger = Logger.getLogger(ReferenceMetaDataMapper.class);

	private ReferenceMetaDataMapper() {
	}

	public static void toXml(ReferenceMetaData metaData, File targetFile) throws FileNotFoundException, NarcissusException {
		targetFile.getParentFile().mkdirs();

		XStream streamer = new XStream();
		addAliases(streamer);

		streamer.toXML(metaData, new BufferedOutputStream(new FileOutputStream(targetFile)));
	}
	
	public static void toXml(Map<Integer,ReferenceMetaData> metaDatas, File targetFile) throws FileNotFoundException{
		targetFile.getParentFile().mkdirs();

		XStream streamer = new XStream();
		addAliases(streamer);

		streamer.toXML(metaDatas, new BufferedOutputStream(new FileOutputStream(targetFile)));
	}

	private static void addAliases(XStream streamer) {
		streamer.alias("MetaData", ReferenceMetaData.class);
		streamer.alias("Exclusion", Rectangle.class);
	}

	public static ReferenceMetaData fromXml(File inputFile) throws NarcissusException {
		if (inputFile == null) {
			return null;
		}

		XStream xmlReader = new XStream();
		addAliases(xmlReader);

		try {
			return (ReferenceMetaData) xmlReader.fromXML(new BufferedInputStream(new FileInputStream(inputFile)));
		} catch (FileNotFoundException impossibleToReadMetaDataFileEx) {
			logger.error("Impossible to read exclusion meta-data from file: " + inputFile == null ? "File parameter is null!" : inputFile.getAbsolutePath(),
			    impossibleToReadMetaDataFileEx);
			throw new NarcissusException(ReferenceMetaDataMapper.class.getName() + ".impossibleToReadMetaDataFileEx", impossibleToReadMetaDataFileEx);
		}
	}
	
	@SuppressWarnings("unchecked")
	public static Map<Integer, ReferenceMetaData> fromXmlMultiple(File inputFile) throws NarcissusException{
		if (inputFile == null || !inputFile.exists()) {
			return null;
		}

		XStream xmlReader = new XStream();
		addAliases(xmlReader);

		try {
			return (Map<Integer, ReferenceMetaData>) xmlReader.fromXML(new BufferedInputStream(new FileInputStream(inputFile)));
		} catch (FileNotFoundException impossibleToReadMetaDataFileEx) {
			logger.error("Impossible to read exclusion meta-data from file: " + inputFile == null ? "File parameter is null!" : inputFile.getAbsolutePath(),
			    impossibleToReadMetaDataFileEx);
			throw new NarcissusException(ReferenceMetaDataMapper.class.getName() + ".impossibleToReadMetaDataFileEx", impossibleToReadMetaDataFileEx);
		}
	}

	/**
	 * From the reference image file location, create a new file pointing to the location of the ReferenceMetaData
	 * 
	 * @param referenceImageFile
	 * @return
	 */
	public static File getMetaDataFile(File referenceImageFile) {
		try {
			String referenceImageFilePath = referenceImageFile.getCanonicalPath();
			return new File(referenceImageFilePath.substring(0, referenceImageFilePath.length() - 4) + ".xml");
		} catch (IOException ex) {
			logger.error("Impossible to computer reference metadata file path from reference image!", ex);
			return null;
		}
	}
	
	public static void main(String[] args) throws FileNotFoundException {
		List<Rectangle> exclusionZones = new ArrayList<Rectangle>();
		
		exclusionZones.add(new Rectangle(0,0,15,20));
		exclusionZones.add(new Rectangle(0,0,150,200));
		exclusionZones.add(new Rectangle(0,0,151,201));
		exclusionZones.add(new Rectangle(0,0,154,204));
		ReferenceMetaData metaData1 = new ReferenceMetaData(exclusionZones);
		metaData1.setComment("ccoucou1");
		metaData1.setCreationDate(new Date());
		Map<Integer,ReferenceMetaData> metaDatas = new HashMap<Integer, ReferenceMetaData>();
		metaDatas.put(1,metaData1);
		ReferenceMetaDataMapper.toXml(metaDatas, new File("/home/rouvq/coucou.metaData"));
	}
}
